<template>
  <el-select
    v-model="valueTitle"
    :placeholder="placeholder"
    clearable
    :disabled="disabled"
    filterable
    @change="handleChange"
  >
    <el-option
      v-for="item in normalizedOptions"
      :key="item.id"
      :label="item.label"
      :value="item.id"
      :disabled="item.disabled"
    >
      <span v-html="item.prefixLabel"></span>
    </el-option>
  </el-select>
</template>

<script setup>
import { ref, watchEffect, computed, defineProps, defineEmits } from 'vue'

const props = defineProps({
  // 选中的值
  modelValue: {
    type: [String, Number],
    default: undefined
  },
  // 选项数据
  options: {
    type: Array,
    default: () => []
  },
  // 选项处理函数
  normalizer: {
    type: Function,
    default: undefined
  },
  // 占位文本
  placeholder: {
    type: String,
    default: '请选择'
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:modelValue', 'change'])

// 选中项的标题
const valueTitle = ref('')

// 使用 normalizer 函数处理选项数据
const normalizeNode = (node, normalizer) => {
  if (normalizer) {
    return normalizer(node)
  }
  return {
    id: node.id,
    label: node.label,
    children: node.children
  }
}

// 扁平化树结构为列表并添加层级缩进
const flattenTree = (nodes, level = 0, parent = null, normalizer) => {
  if (!nodes || nodes.length === 0) return []
  
  let result = []
  const prefix = Array(level).fill('&nbsp;&nbsp;').join('')
  
  nodes.forEach(node => {
    const normalized = normalizeNode(node, normalizer)
    const prefixLabel = level > 0 ? `${prefix}├─ ${normalized.label}` : normalized.label
    
    result.push({
      id: normalized.id,
      label: normalized.label,
      prefixLabel,
      disabled: !!node.disabled
    })
    
    if (normalized.children && normalized.children.length > 0) {
      const children = flattenTree(normalized.children, level + 1, normalized, normalizer)
      result = result.concat(children)
    }
  })
  
  return result
}

// 处理后的选项
const normalizedOptions = computed(() => flattenTree(props.options, 0, null, props.normalizer))

// 处理选择变化
const handleChange = (val) => {
  emit('update:modelValue', val)
  emit('change', val)
}

// 根据选中值设置显示文本
watchEffect(() => {
  if (props.modelValue === undefined || props.modelValue === null || props.modelValue === '') {
    valueTitle.value = ''
    return
  }
  
  const selected = normalizedOptions.value.find(item => item.id === props.modelValue)
  valueTitle.value = selected ? props.modelValue : ''
})
</script>

<style scoped>
:deep(.el-select-dropdown__item span) {
  white-space: nowrap;
}
</style> 